package dbConnector

import (
	"database/sql"
	"fmt"
	"net/url"
	"sync"
)

import (
	"code.google.com/p/gcfg"
	_ "github.com/denisenkom/go-mssqldb"
)

type ServerList struct {
	Holiday    ServerInfo             //假日表数据
	ModelLevel ServerInfo             //模型评级和确认池评级数据
	BoardInfo  ServerInfo             //板块信息数据
	Account    map[string]*ServerInfo //账户信息，确认池股票信息，加建仓信息数据
	Statistic  ServerInfo
}

type ServerInfo struct {
	DataBase string
	Host     string
	Port     int
	UserName string
	Password string
	IsSAcc   uint8
	DB       *sql.DB
}

var Servers ServerList
var ServerLock sync.RWMutex

//创建数据库连接
func (si *ServerInfo) InitSqlServer() error {
	u := &url.URL{
		Scheme:   "sqlserver",
		User:     url.UserPassword(si.UserName, si.Password),
		Host:     fmt.Sprintf("%v:%v", si.Host, si.Port),
		RawQuery: url.Values{"database": []string{si.DataBase}}.Encode(),
	}

	db, err := sql.Open("mssql", u.String())
	if err != nil {
		return err
	}
	db.SetMaxIdleConns(20)
	db.SetMaxOpenConns(50)
	db.SetConnMaxLifetime(1000)
	si.DB = db
	return nil
}

func OpenServerList() error {
	err := Servers.Holiday.InitSqlServer()
	if err != nil {
		return fmt.Errorf("OpenServerList(%v): %v", Servers.Holiday, err)
	}
	err = Servers.ModelLevel.InitSqlServer()
	if err != nil {
		return fmt.Errorf("OpenServerList(%v): %v", Servers.ModelLevel, err)
	}
	err = Servers.BoardInfo.InitSqlServer()
	if err != nil {
		return fmt.Errorf("OpenServerList(%v): %v", Servers.BoardInfo, err)
	}
	for _, v := range Servers.Account {
		err = v.InitSqlServer()
		if err != nil {
			return fmt.Errorf("OpenServerList(%v): %v", v, err)
		}
	}
	err = Servers.Statistic.InitSqlServer()
	if err != nil {
		return fmt.Errorf("OpenServerList(%v): %v", Servers.Statistic, err)
	}
	return nil
}

func CloseServerList() {
	ServerLock.Lock()
	Servers.Holiday.DB.Close()
	Servers.ModelLevel.DB.Close()
	Servers.BoardInfo.DB.Close()
	for _, v := range Servers.Account {
		v.DB.Close()
	}
	Servers.Statistic.DB.Close()
	ServerLock.Unlock()
}

//更新数据库列表信息
func UpdateServerList(confPath string) error {
	return initServerList(confPath)
}

//初始化数据库列表信息
func initServerList(confPath string) error {
	sl, err := configLoad(confPath)
	if err != nil {
		return fmt.Errorf("Failed to read config of server list from '%s', %v", confPath, err)
	}
	ServerLock.Lock()
	Servers = sl
	err = OpenServerList()
	if err != nil {
		return err
	}
	ServerLock.Unlock()
	return nil
}

func configLoad(confPath string) (ServerList, error) {
	var sl ServerList
	var err error

	err = gcfg.ReadFileInto(&sl, confPath)
	if err != nil {
		return sl, fmt.Errorf("gcfg.ReadFileInto(): %s", err.Error())
	}

	return sl, nil
}
